/*
 * MIT License
 *
 * Copyright (c) 2025 Mark·虎
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

package com.hsxxherp.key.uia.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.hsxxherp.key.uia.entity.SysApplicationVersion;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 应用版本服务接口
 * 该接口继承自 MyBatis-Plus 提供的 IService 接口，可使用其内置的通用服务方法，
 * 同时定义了应用版本相关的特定业务操作方法，如创建、更新和删除版本等。
 *
 * @author Mark·虎（2486970363@qq.com）
 */
public interface ISysApplicationVersionService extends IService<SysApplicationVersion> {

    /**
     * 创建应用版本
     * 此方法用于在系统中创建一个新的应用版本记录。
     * 在创建过程中，会对版本号的合法性进行检查，确保版本号不为空且该应用下不存在相同版本号的记录。
     * 若创建成功，会将版本的发布时间设置为当前时间，同时将版本状态初始化为“已创建”，部署状态初始化为“未部署”，
     * 并返回创建好的应用版本对象；若创建失败，则返回 null。
     *
     * @param version 要创建的应用版本对象，包含版本的基本信息，如版本号、应用 ID、版本描述等
     * @return 创建成功的应用版本对象，如果创建失败则返回 null
     * @throws RuntimeException 当版本号为空或者该应用下已存在相同版本号的记录时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion createVersion(SysApplicationVersion version);

    /**
     * 更新应用版本
     * 此方法用于更新系统中已存在的应用版本记录。
     * 在更新前，会检查要更新的版本是否存在，以及更新后的版本号是否合法（不为空且不与该应用下其他版本重复）。
     * 若更新成功，会将版本的发布时间更新为当前时间，并返回更新后的应用版本对象；若更新失败，则返回 null。
     *
     * @param version 包含更新信息的应用版本对象，需指定要更新的版本 ID 以及要更新的字段信息，如版本号、版本描述等
     * @return 更新成功的应用版本对象，如果更新失败则返回 null
     * @throws RuntimeException 当要更新的版本不存在、版本号为空或者该应用下已存在相同版本号的记录时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion updateVersion(SysApplicationVersion version);

    /**
     * 删除应用版本
     * 此方法用于从系统中删除指定 ID 的应用版本记录。
     * 在删除前，会检查要删除的版本是否存在。
     * 若删除成功，会记录成功日志并返回 true；若删除失败，会记录错误日志并返回 false。
     *
     * @param versionId 要删除的应用版本的唯一标识
     * @return 如果删除成功返回 true，否则返回 false
     * @throws RuntimeException 当要删除的版本不存在时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    boolean deleteVersion(String versionId);

    /**
     * 发布应用版本
     * 此方法用于将已部署的应用版本进行发布操作。
     * 在发布前，会检查要发布的版本是否存在，并且其部署状态是否为“已部署”。
     * 若满足条件，会将版本状态更新为“已发布”，并更新发布时间，然后返回更新后的应用版本对象；若发布失败，则返回 null。
     *
     * @param versionId 要发布的应用版本的唯一标识
     * @return 发布成功的应用版本对象，如果发布失败则返回 null
     * @throws RuntimeException 当要发布的版本不存在或者其部署状态不为“已部署”时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion publishVersion(String versionId);

    /**
     * 回滚应用版本
     * 此方法用于将已发布的应用版本回滚到前一个版本。
     * 在回滚前，会检查要回滚的版本是否存在，是否为“已发布”状态，以及前一个版本是否存在。
     * 若满足条件，会将当前版本状态更新为“已回滚”，将前一个版本状态更新为“已发布”，并更新前一个版本的发布时间，
     * 然后返回回滚到的目标版本对象；若回滚失败，则返回 null。
     *
     * @param versionId 要回滚的应用版本的唯一标识
     * @return 回滚到的目标应用版本对象，如果回滚失败则返回 null
     * @throws RuntimeException 当要回滚的版本不存在、不是“已发布”状态、没有前一个版本或者前一个版本不存在时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion rollbackVersion(String versionId);

    /**
     * 开始应用版本测试
     * 此方法用于将已创建的应用版本开始进行测试操作。
     * 在开始测试前，会检查要开始测试的版本是否存在，并且其版本状态是否为“已创建”。
     * 若满足条件，会将版本状态更新为“测试中”，然后返回更新后的应用版本对象；若操作失败，则返回 null。
     *
     * @param versionId 要开始测试的应用版本的唯一标识
     * @return 开始测试操作成功的应用版本对象，如果操作失败则返回 null
     * @throws RuntimeException 当要开始测试的版本不存在或者其版本状态不为“已创建”时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion startTesting(String versionId);

    /**
     * 开始应用版本部署
     * 此方法用于将处于测试中或已回滚状态且未部署的应用版本开始进行部署操作。
     * 在开始部署前，会检查要开始部署的版本是否存在，版本状态是否为“测试中”或“已回滚”，以及部署状态是否为“未部署”。
     * 若满足条件，会将部署状态更新为“部署中”，然后返回更新后的应用版本对象；若操作失败，则返回 null。
     *
     * @param versionId 要开始部署的应用版本的唯一标识
     * @return 开始部署操作成功的应用版本对象，如果操作失败则返回 null
     * @throws RuntimeException 当要开始部署的版本不存在、版本状态不符合要求或者部署状态不为“未部署”时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion startDeployment(String versionId);

    /**
     * 标记应用版本部署成功
     * 此方法用于将处于部署中的应用版本标记为部署成功。
     * 在标记前，会检查要标记的版本是否存在，并且其部署状态是否为“部署中”。
     * 若满足条件，会将部署状态更新为“已部署”，然后返回更新后的应用版本对象；若操作失败，则返回 null。
     *
     * @param versionId 要标记部署成功的应用版本的唯一标识
     * @return 标记部署成功操作成功的应用版本对象，如果操作失败则返回 null
     * @throws RuntimeException 当要标记的版本不存在或者其部署状态不为“部署中”时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion markDeploymentSuccess(String versionId);

    /**
     * 标记应用版本部署失败
     * 此方法用于将处于部署中的应用版本标记为部署失败。
     * 在标记前，会检查要标记的版本是否存在，并且其部署状态是否为“部署中”。
     * 若满足条件，会将部署状态更新为“部署失败”，然后返回更新后的应用版本对象；若操作失败，则返回 null。
     *
     * @param versionId 要标记部署失败的应用版本的唯一标识
     * @return 标记部署失败操作成功的应用版本对象，如果操作失败则返回 null
     * @throws RuntimeException 当要标记的版本不存在或者其部署状态不为“部署中”时抛出此异常
     */
    @Transactional(rollbackFor = Exception.class)
    SysApplicationVersion markDeploymentFailed(String versionId);

    /**
     * 根据应用 ID 获取已发布的应用版本列表
     * 此方法用于从系统中查询指定应用 ID 下所有已发布的应用版本记录。
     *
     * @param appId 应用的唯一标识
     * @return 包含指定应用 ID 下所有已发布应用版本对象的列表，如果没有符合条件的版本则返回空列表
     */
    List<SysApplicationVersion> getPublishedVersionsByAppId(String appId);
}